﻿//-----------------------------------------------------------------------
// <copyright file="IProductManager.cs" company="Streetlight Technologies L.L.C.">
//    Copyright Streetlight Technologies L.L.C. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace Streetlight.Store.Contracts
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// Provides an interface for managing product data.
    /// </summary>
    public interface IProductManager
    {
        /// <summary>
        /// Returns a list of all products.
        /// </summary>
        /// <returns>New instance of List&lt;Product&gt; containing data for all products</returns>
        List<Product> ListAll();

        /// <summary>
        /// Stores the provided Product as a new record.
        /// </summary>
        /// <param name="product">Product to be saved</param>
        void CreateNew(Product product);

        /// <summary>
        /// Checks to see if a product exists with the specified item number and different
        /// ID.  This function can be used to ensure exclusivity of item numbers.  Returns true
        /// if a product exists with the specified item number and different ID, otherwise
        /// returns false.
        /// </summary>
        /// <param name="id">ID of item to validate item number for.  If parameter is null,
        /// empty, or whitespace, all existing items will be searched.</param>
        /// <param name="itemNumber">Item number to check for duplicates</param>
        /// <returns>True if a product exists with the specified product number and different ID, 
        /// otherwise false.</returns>
        bool DuplicateItemNumberExists(string id, string itemNumber);

        /// <summary>
        /// Checks to see if a product exists with the specified global ID and manufacturer and 
        /// different ID.  This function can be used to ensure exclusivity of Global ID/
        /// Manufacturer combinations.  Returns true if a product exists with the specified 
        /// global ID and manufacturer and different ID, otherwise returns false.
        /// </summary>
        /// <param name="id">ID of item to validate item number for.  If parameter is null,
        /// empty, or whitespace, all existing items will be searched.</param>
        /// <param name="globalId">Global ID to find duplicates for</param>
        /// <param name="manufacturer">Manufacturer to find duplicates for</param>
        /// <returns>True if a product exists with the specified 
        /// global ID and manufacturer and different ID, otherwise false.</returns>
        bool DuplicateGlobalIdManufacturerExists(string id, string globalId, string manufacturer);

        /// <summary>
        /// Gets the product with the specified id.
        /// </summary>
        /// <param name="id">ID of product to retrieve</param>
        /// <returns>New instance of Product with data for provided ID.</returns>
        Product GetProduct(string id);

        /// <summary>
        /// Saves the provided Product as an existing record.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">Thrown when no product is found for the ID
        /// provided as product.Id.</exception>
        /// <param name="product">Product to save</param>
        void Save(Product product);

        /// <summary>
        /// Returns a list of all categories.
        /// </summary>
        /// <returns>New instance of List&lt;ProductCategory&gt; containing data for all categories</returns>
        List<ProductCategory> ListAllCategories();

        /// <summary>
        /// Stores the category provided as a new record.
        /// </summary>
        /// <param name="category">Category to be saved</param>
        void CreateNewCategory(ProductCategory category);

        /// <summary>
        /// Gets the category with the specified ID.
        /// </summary>
        /// <param name="id">ID of category to return</param>
        /// <returns>New instance of ProductCategory with data for provided ID.</returns>
        ProductCategory GetCategory(string id);

        /// <summary>
        /// Saves the provided category as an existing record.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">Thrown when no category is found for the ID
        /// provided as category.Id.</exception>
        /// <param name="category">Category to save</param>
        void SaveCategory(ProductCategory category);

        /// <summary>
        /// Lists categories associated with the specified ID.
        /// </summary>
        /// <param name="id">ID of product to list categories for</param>
        /// <returns>New instance of List&lt;ProductCategory&gt; containing categories associated with product.</returns>
        List<ProductCategory> ListCategoriesForProduct(string id);

        /// <summary>
        /// Adds the product with the specified ID to the category with the specified ID.  If a relationship
        /// already exists, nothing is done.
        /// </summary>
        /// <param name="productId">ID of product to add</param>
        /// <param name="categoryId">ID of category to add to</param>
        void AddProductToCategory(string productId, string categoryId);

        /// <summary>
        /// Removes the product with the specified ID from the category with the specified ID.  If no relationship
        /// exists, nothing is done.
        /// </summary>
        /// <param name="productId">ID of product to remove</param>
        /// <param name="categoryId">ID of category to remove from</param>
        void RemoveProductFromCategory(string productId, string categoryId);
    }
}
